package com.itc.bi.handler.datasource;

import com.alibaba.fastjson2.JSONObject;
import com.itc.bi.constant.SystemConstant;
import com.itc.bi.entity.DatasourceEntity;
import com.itc.bi.entity.TableColumnEntity;
import com.itc.bi.entity.TableEntity;
import com.itc.bi.handler.DatasourceHandler;
import com.itc.common.core.exception.ServiceException;
import lombok.extern.log4j.Log4j2;
import oracle.sql.TIMESTAMP;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.*;

@Log4j2
public class OracleDatasource extends DatasourceHandler {

    public OracleDatasource(DatasourceEntity entity){
        super(entity);
    }

    @Override
    public void sqlInit(){
        switch (type){
            case SystemConstant.JDBC_SQL_TYPE_TABLE:
                sql = "SELECT user,user,table_name,comments from user_tab_comments";
                return;
            case SystemConstant.JDBC_SQL_TYPE_COLUMN:
                sql = "SELECT t.TABLE_NAME,t.COLUMN_NAME,cc.COMMENTS,t.DATA_TYPE,t.data_length,t.data_precision,t.data_scale,t.column_id,t.DATA_DEFAULT,t.NULLABLE FROM USER_TAB_COLUMNS t JOIN USER_COL_COMMENTS cc on cc.table_name=t.table_name and cc.column_name = t.column_name";
                return;
            case SystemConstant.JDBC_SQL_TYPE_VERSION:
                sql = "select version from product_component_version";
                return;
            case SystemConstant.JDBC_SQL_TYPE_SQL_PAGE:

                sql = "select page.* from ( select t.*，rownum rownum_rn from ("
                +sql+") t where rownum < " +(pageStartIndex+pageSize+1)+") page where page.rownum_rn > "+pageStartIndex;
                return;
            case SystemConstant.JDBC_SQL_TYPE_SQL_PAGE_COUNT:
                sql = "select count(*) from ("+sql+")";
                return;
            default:return;
        }
    }
    @Override
    public void result(ResultSet re) throws SQLException {
        switch (type){
            case SystemConstant.JDBC_SQL_TYPE_COLUMN:
                while (re.next()){
                    TableColumnEntity column = new TableColumnEntity();
                    column.setTableName(re.getString(1));
                    column.setColumnName(re.getString(2));
                    column.setColumnComment(re.getString(3));

                    String type = re.getString(4);
                    String length = re.getString(5);
                    String precision = re.getString(6);
                    String scale = re.getString(7);
                    //字段类型处理
                    if(StringUtils.isNoneBlank(precision,scale)){
                        type = type+"("+precision+","+scale+")";
                    }else{
                        type = type+"("+length+")";
                    }

                    column.setColumnType(type);
                    column.setColumnPosition(re.getInt(8));
                    column.setDefaultValue(re.getString(9));
                    column.setIsNullable(re.getString(10));
                    columnList.add(column);
                }
                return;
            case SystemConstant.JDBC_SQL_TYPE_SQL:
            case SystemConstant.JDBC_SQL_TYPE_SQL_PAGE:
                ResultSetMetaData meta = re.getMetaData();
                List<String> lables = new ArrayList<>();
                for (int i = 1; i <=  meta.getColumnCount(); i++) {
                    //移除oracle分页添加的分页行号
                    if("rownum_rn".equalsIgnoreCase(meta.getColumnLabel(i))){
                        continue;
                    }
                    lables.add(meta.getColumnLabel(i));
                }
                while (re.next()){
                    JSONObject data = new JSONObject();
                    for (int i = 0; i < lables.size(); i++) {
                        Object value = re.getObject(i+1);
                        //oracle特有类型TIMESTAMP接口返回异常
                        if(value instanceof TIMESTAMP){
                            value = Timestamp.valueOf(((TIMESTAMP)value).stringValue());
                        }
                        data.put(lables.get(i),value);
                    }
                    jsonArray.add(data);
                }
                return;
            default:
                super.result(re);
                return;
        }
    }
}
